home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1999 November
/
Macworld (1999-11).dmg
/
Updaters
/
WhiteCap 3.0.4
/
WhiteCap Source.sit
/
WhiteCap Source
/
SJ SDK
/
VisFrameworkHandlers.c
< prev
next >
Wrap
Text File
|
1999-08-30
|
25KB
|
753 lines
/*==========================================================================
----------------------------------------------------------------------------
VisFrameworkHandlers.c
version 1.0.0
Mike Wright
darwin@mbay.net
Handlers for each of the messages that SoundJam sends to visual plug-ins.
----------------------------------------------------------------------------
============================================================================*/
#include "Debug.h"
#include "VisFramework.h"
#include "WhiteCap.h"
#include "CEgFileSpec.h"
#include "EgOSUtils.h"
/*========================================================================== Functions */
/* ————————————————————————— HandleInitializeMessage ——————————————————————————————
Purpose: Initializes the module. Called on first entry.
Some of the tasks this function should perform are:
1. fill in VisHandlerData struct fields from fields in
messageInfo->u.initMessage
2. preload any resources and move the data into VisHandlerData
3. retrieve preferences that were saved in HandleCancelMessage()
by calling PlayerGetPluginData()
Since the plugin must coexist with the SoundJam app, it is important
to use as little memory as possible, and to try using temporary
memory for any really large data structures.
It is not a bad idea to fill in small variables and leave the
allocation of large handles/pointers to the HandleEnableMessage()
function whenever that is possible.
messageInfo is a pointer to a message containing:
struct VisualPluginInitMessage
{
UInt32 version; // Input
void * appCookie; // Input
SoundJamProcPtr playerProc; // Input
OptionBits options; // Output
void *refcon; // Output
}
———————————————————————————————————————————————————————————————————————————————————
Arguments: messageInfo - pointer to a VisualPluginInitMessage struct
plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleInitializeMessage (VisualPluginMessageInfo *messageInfo,VisHandlerData *plugInData)
{
//VisPluginPrefs plugInPrefs; /* stuct for getting our preferences back from SoundJam */
//UInt32 dataSize;
OSStatus status = noErr;
/* allocate storage for plugInData */
plugInData = (VisHandlerData *)NewPtrClear(sizeof(VisHandlerData));
/* if NewPtrClear() fails, bail out */
require_action(plugInData,bail,status = memFullErr;);
/* move messageInfo fields into corresponding plugInData fields */
plugInData->appCookie = messageInfo->u.initMessage.appCookie;
plugInData->playerProc = messageInfo->u.initMessage.playerProc;
plugInData->version = messageInfo->u.initMessage.version;
/* fill in framework-specific fields */
plugInData->magic = cWhiteCapID;
plugInData->visEnabled = false;
plugInData -> mWC = NULL;
EgOSUtils::Initialize();
PixPort::Startup();
long prefDepth = PixPort::sOSDepth;
PlayerSetDefaultWindowSize ( messageInfo->u.initMessage.appCookie, messageInfo->u.initMessage.playerProc,
400,
300,
80,
50,
10000,
10000);
PlayerSetFullScreenOptions ( messageInfo->u.initMessage.appCookie, messageInfo->u.initMessage.playerProc, 0, 32, prefDepth, 640, 480 );
/* Stuff plugInData storage into the refcon */
messageInfo->u.initMessage.refcon = (void *)plugInData;
bail:
return status;
} /* end HandleInitializeMessage */
/* ——————————————————————————— HandleCleanupMessage ———————————————————————————————
Purpose: Disposes of all plugInData handles and pointers.
We set the fields in plugInPrefs to the corresponding fields in
plugInData and pass plugInPrefs to SoundJam via PlayerSetPluginData().
These fields are retrieved by HandleInitializeMessage by calling
PlayerGetPluginData().
If plugInData contained any locally allocated pointers or handles,
we would dispose them here, but the framework sample has none.
We do dispose plugInData itself.
———————————————————————————————————————————————————————————————————————————————————
Arguments: plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleCleanupMessage (VisHandlerData *plugInData)
{
//VisPluginPrefs plugInPrefs; /* stuct for passing our preferences to SoundJam */
OSStatus status = noErr;
/* Make sure it's us! */
require_action(plugInData,bail,status = paramErr;);
require_action(plugInData->magic == cWhiteCapID,bail,status = paramErr;);
PixPort::Shutdown();
/* dispose of plugInData itself */
DisposePtr((Ptr)plugInData);
bail:
return status;
} /*end HandleCleanupMessage */
#pragma mark -
/* ——————————————————————————— HandleEnableMessage ————————————————————————————————
Purpose: Turns on the module.
This is where you should allocate memory for drawing, including
GWorldPtrs.
———————————————————————————————————————————————————————————————————————————————————
Arguments: plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleEnableMessage (VisHandlerData *plugInData)
{
OSStatus status = noErr;
#pragma unused( plugInData )
/* allocate your drawing memory here */
bail:
return status; /* the framework sample always returns noErr */
} /* end HandleEnableMessage */
/* ——————————————————————————— HandleDisableMessage ———————————————————————————————
Purpose: Turns off the module.
Disposes of all global VisHandlerData handles and pointers that were
allocated in HandleEnableMessage().
It is particularly important not to leave memory allocated that will
be re-allocated at the next call to HandleEnableMessage(), as this
could quickly grow to a very large memory leak.
———————————————————————————————————————————————————————————————————————————————————
Arguments: plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleDisableMessage (VisHandlerData *plugInData)
{
OSStatus status = noErr;
#pragma unused( plugInData )
/* dispose memory allocated in HandleEnableMessage() here */
return status; /* the framework sample always returns noErr */
} /* end HandleDisableMessage */
#pragma mark -
/* ————————————————————————— HandleShowWindowMessage ——————————————————————————————
Purpose: Window is visible. Get the current port and drawing rectangle from
messageInfo. We also set visEnabled to true.
messageInfo is a pointer to a message containing:
VisualPluginShowWindowMessage
{
CGrafPtr port;
Rect drawRect;
}
———————————————————————————————————————————————————————————————————————————————————
Arguments: messageInfo - pointer to a VisualPluginShowWindowMessage struct
plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleShowWindowMessage (VisualPluginMessageInfo *messageInfo, VisHandlerData *plugInData)
{
OSStatus status = noErr;
plugInData->visEnabled = true;
/* move messageInfo fields into corresponding plugInData fields */
plugInData->port = messageInfo->u.showWindowMessage.port;
plugInData->drawRect = messageInfo->u.showWindowMessage.drawRect;
if ( ! plugInData -> mWC ) {
CEgFileSpec folder;
folder.AssignFolder( "WhiteCap Configs" );
plugInData -> mWC = new WhiteCap( folder, plugInData );
plugInData -> mWC -> SetPort( (GrafPtr) plugInData->port, plugInData->drawRect, ((messageInfo->u.showWindowMessage.options & kWindowIsFullScreen) != 0) );
}
bail:
return status; /* the framework sample always returns noErr */
} /* end HandleShowWindowMessage */
/* ————————————————————————— HandleSetWindowMessage ——————————————————————————————
Purpose: Window dimensions and/or port have changed. This is called on behalf
of window resizing and fullscreen toggles. If this call returns an
error, the app will do a hide/show combination instead.
———————————————————————————————————————————————————————————————————————————————————
Arguments: plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleSetWindowMessage (VisualPluginMessageInfo *messageInfo, VisHandlerData *plugInData)
{
/* move messageInfo fields into corresponding plugInData fields */
plugInData->port = messageInfo->u.setWindowMessage.port;
plugInData->drawRect = messageInfo->u.setWindowMessage.drawRect;
if ( plugInData -> mWC ) {
plugInData -> mWC -> SetPort( (GrafPtr) plugInData->port, plugInData->drawRect, ((messageInfo->u.setWindowMessage.options & kWindowIsFullScreen) != 0));
}
return noErr;
}
/* ————————————————————————— HandleHideWindowMessage ——————————————————————————————
Purpose: Window is hidden. We set visEnabled to false.
———————————————————————————————————————————————————————————————————————————————————
Arguments: plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleHideWindowMessage (VisHandlerData *plugInData)
{
OSStatus status = noErr;
plugInData->visEnabled = false;
if ( plugInData -> mWC ) {
delete plugInData -> mWC;
plugInData -> mWC = NULL;
}
bail:
return status; /* the framework sample always returns noErr */
} /* end HandleHideWindowMessage */
#pragma mark -
/* ——————————————————————————— HandleResizeMessage ————————————————————————————————
Purpose: User has resized the visual plugin window. Look at the desired
width and height, and pass back a width and height that is suitable
for your plugin in the approvedWidth and approvedHeight fields of
messageInfo.
(SJ 1.0.0b11 doesn't handle this yet.)
The framework sample requires a square window, so we set both dimensions
to the smaller of the two desired dimensions.
messageInfo is a pointer to a message containing:
VisualPluginResizeMessage
{
SInt16 desiredWidth; // Input
SInt16 desiredHeight; // Input
SInt16 approvedWidth; // Output
SInt16 approvedHeight; // Output
}
———————————————————————————————————————————————————————————————————————————————————
Arguments: messageInfo - pointer to a VisualPluginResizeMessage struct
plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleResizeMessage (VisualPluginMessageInfo *messageInfo,VisHandlerData *plugInData)
{
messageInfo->u.resizeMessage.approvedWidth = messageInfo->u.resizeMessage.desiredWidth;
messageInfo->u.resizeMessage.approvedHeight = messageInfo->u.resizeMessage.desiredHeight;
#pragma unused( plugInData )
return noErr;
} /* end HandleResizeMessage */
#pragma mark -
/* ———————————————————————————— HandlePlayMessage ————————————————————————————————
Purpose: Handles new track info.
messageInfo is a pointer to a message containing:
struct VisualPluginPlayMessage
{
TrackSpec *trackSpec; // Input--don't cache, copy out data only valid during call
SInt32 volume; // Input
UInt32 bitRate; // Input
SoundComponentData soundFormat; // Input
}
———————————————————————————————————————————————————————————————————————————————————
Arguments: messageInfo - pointer to a VisualPluginPlayMessage struct
plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandlePlayMessage (VisualPluginMessageInfo *messageInfo,VisHandlerData *plugInData)
{
OSStatus status = noErr;
/* move messageInfo fields into corresponding plugInData fields */
plugInData->trackSpec = messageInfo->u.playMessage.trackSpec;
plugInData->volume = messageInfo->u.playMessage.volume;
plugInData->bitRate = messageInfo->u.playMessage.bitRate;
BlockMoveData((Ptr)&messageInfo->u.playMessage.soundFormat,(Ptr)&plugInData->soundFormat,sizeof(SoundComponentData));
/* the framework sample just erases the display */
//ResetVisual(plugInData);
return status; /* the framework sample always returns noErr */
} /* end HandlePlayMessage */
/* ———————————————————————————— HandleStopMessage —————————————————————————————————
Purpose: Responds to the stopping of the current track.
———————————————————————————————————————————————————————————————————————————————————
Arguments: plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleStopMessage ( VisHandlerData *plugInData)
{
OSStatus status = noErr;
for ( int i = 0; i < NUM_SAMPLE_BINS; i++ ) {
plugInData -> mSample[ i ] = 0;
}
return status; /* the framework sample always returns noErr */
} /* end HandleStopMessage */
#pragma mark -
/* ——————————————————————————— HandlePauseMessage —————————————————————————————————
Purpose: Responds to the pausing of the current track by setting
plugInData->visEnabled = false, which will prevent any modification
of the module window.
———————————————————————————————————————————————————————————————————————————————————
Arguments: plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandlePauseMessage ( VisHandlerData *plugInData)
{
OSStatus status = noErr;
#pragma unused( plugInData )
return status; /* the framework sample always returns noErr */
} /* end HandlePauseMessage */
/* —————————————————————————— HandleUnpauseMessage ————————————————————————————————
Purpose: Responds to the unpausing of the current trackby setting
plugInData->visEnabled = true, which will permit the modification
of the module window.
———————————————————————————————————————————————————————————————————————————————————
Arguments: plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleUnpauseMessage ( VisHandlerData *plugInData)
{
OSStatus status = noErr;
#pragma unused( plugInData )
return status; /* the framework sample always returns noErr */
} /* end HandleUnpauseMessage */
#pragma mark -
/* ——————————————————————————— HandleRenderMessage ————————————————————————————————
Purpose: Renders some data visually.
messageInfo is a pointer to a message containing:
struct VisualPluginRenderMessage
{
RenderVisualData *renderData;
}
———————————————————————————————————————————————————————————————————————————————————
Arguments: messageInfo - pointer to a VisualPluginRenderMessage struct
plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleRenderMessage (VisualPluginMessageInfo *messageInfo,VisHandlerData *plugInData)
{
OSStatus status = noErr;
/* For the framework sample module, we're just getting the first 256 */
/* bytes of spectrumData. You may want to get all of renderData */
//BlockMoveData(&messageInfo->u.renderMessage.renderData,&plugInData->renderData,sizeof(RenderVisualData));
/* if we're not enabled, we don't draw */
if ( plugInData->visEnabled || 1 ) {
// ##############
int i, j;
/*
gPlugInfo.ma->GetFFT( &samp, &fftNum );
if ( gPlugInfo.ma->GetStatus )
gPlugInfo.ma->GetStatus( &time, &status );
if ( fftNum < NUM_SAMPLE_BINS * 11 + 10 || ( status & statusStopped ) ) {
for ( i = 0; i < NUM_SAMPLE_BINS; i++ ) {
plugInData -> mSample[ i ] = 0;
}
}
else {
bin = 10;
for ( i = 0; i < NUM_SAMPLE_BINS; i++ ) {
gSample[ i ] = 0;
for ( j = 0; j < 11; j++, bin++ )
gSample[ i ] += samp[ bin ];
}
bin = 10;
for ( i = 0; i < NUM_SAMPLE_BINS; i++ ) {
for ( j = 0; j < 11; j++, bin++ )
gSample[ i ] += samp[ bin ];
// gSample[ i ] = .03 * .0003 * gSample[ i ] * (0.85 + .059 * i);
// gSample[ i ] = .1 * ( sqrt( 15 + .0003 * gSample[ i ] * (0.85 + .059 * i) ) - sqrt( 15 ) );
gSample[ i ] = .13 * ( sqrt( 40 + .0003 * gSample[ i ] * (0.85 + .059 * i) ) - sqrt( 40 ) );
}
gSample[ 0 ] *= 0.45;
gSample[ 1 ] *= 0.75;
}*/
RenderVisualData* data = messageInfo->u.renderMessage.renderData;
float factor, binVal;
long sum, idx = 10;
for ( i = 0; i < NUM_SAMPLE_BINS; i++ ) {
sum = 0;
for ( j = 0; j < 5; j++, idx++ )
sum += ((unsigned) data -> spectrumData[0][idx]);
plugInData -> mSample[ i ] = sum;
}
idx = 10;
for ( i = 0; i < NUM_SAMPLE_BINS; i++ ) {
sum = 0;
for ( j = 0; j < 5; j++, idx++ )
sum += ((unsigned) data -> spectrumData[1][idx]);
binVal = ((float) sum + plugInData -> mSample[ i ]) * (0.87 + (float) i / 47.0) / (1400.0);
factor = .6 + .3 / ( 1.56 * binVal + .5 );
if ( factor < 1 )
binVal *= factor;
plugInData -> mSample[ i ] = UNIV_MAG_SCALE * binVal;
}
plugInData -> mSample[ 0 ] *= 0.45;
plugInData -> mSample[ 1 ] *= 0.75;
// Store the newest sample and chuck and old samples
plugInData -> mWC -> RecordSample( EgOSUtils::CurTimeMS(), plugInData -> mSample );
// Update the screen, baby. Let's shag!
plugInData -> mWC -> Draw();
}
return status;
} /* end HandleRenderMessage */
#pragma mark -
/* ——————————————————————— HandleProcessSamplesMessage ————————————————————————————
Purpose: Processes sound data.
You may modify the sound data in *sampleBuffer, but its size must
not be increased beyond the value in maxSamples, which indicates the
maximum available buffer space.
messageInfo is a pointer to a message containing:
struct VisualPluginProcessSamplesMessage
{
UInt32 timeStampID; // Input
SInt16 *sampleBuffer; // Input
UInt32 numSamples; // Input
UInt32 maxSamples; // Input
UInt32 numOutputSamples; // Output (must be <= maxSamples)
}
———————————————————————————————————————————————————————————————————————————————————
Arguments: messageInfo - pointer to a VisualPluginProcessSamplesMessage struct
plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleProcessSamplesMessage (VisualPluginMessageInfo *messageInfo,VisHandlerData *plugInData)
{
OSStatus status = noErr;
/* move messageInfo fields into corresponding plugInData fields */
plugInData->timeStampID = messageInfo->u.processSamplesMessage.timeStampID;
plugInData->sampleBuffer = messageInfo->u.processSamplesMessage.sampleBuffer;
plugInData->numSamples = messageInfo->u.processSamplesMessage.numSamples;
plugInData->maxSamples = messageInfo->u.processSamplesMessage.maxSamples;
plugInData->numOutputSamples = messageInfo->u.processSamplesMessage.numSamples; //init to numSamples
/* the framework sample does not actually handle this message */
return status; /* the framework sample always returns noErr */
} /* end HandleProcessSamplesMessage */
/* ———————————————————————— HandleFlushSamplesMessage —————————————————————————————
Purpose: Sound data is no longer valid. Dispose of your data and prepare to
receive new data.
Processes sound data.
———————————————————————————————————————————————————————————————————————————————————
Arguments: plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleFlushSamplesMessage (VisHandlerData *plugInData)
{
OSStatus status = noErr;
/* zero out sound sample */
plugInData->timeStampID = 0;
plugInData->sampleBuffer = nil;
plugInData->numSamples = 0;
plugInData->maxSamples = 0;
plugInData->numOutputSamples = 0;
return status; /* the framework sample always returns noErr */
} /* end HandleFlushSamplesMessage */
#pragma mark -
/* ——————————————————————————— HandleEventMessage ————————_————————————————————————
Purpose: Handles a Mac event.
The events will be limited to mouse clicks and keystrokes.
If a keyDown message is not handled, this routine should return
paramErr or something else other than noErr, in order to avoid
swallowing unused keystrokes.
messageInfo is a pointer to a message containing:
struct VisualPluginEventMessage
{
EventRecord *event;
}
———————————————————————————————————————————————————————————————————————————————————
Arguments: messageInfo - pointer to a VisualPluginEventMessage
plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleEventMessage (VisualPluginMessageInfo *messageInfo,VisHandlerData *plugInData)
{
OSStatus status = noErr;
switch (messageInfo->u.eventMessage.event->what)
{
case mouseDown:
HandlePlugInMouseDown(plugInData,messageInfo->u.eventMessage.event);
break;
case keyDown:
status = paramErr;
break;
default:
break;
}
return status; /* the framework sample always returns noErr */
} /* end HandleEventMessage */
/* ——————————————————————————— HandleUpdateMessage ————————————————————————————————
Purpose: Equivalent of a Mac update event.
———————————————————————————————————————————————————————————————————————————————————
Arguments: plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleUpdateMessage (VisHandlerData *plugInData)
{
if ( plugInData -> mWC ) {
plugInData -> mWC -> RefreshRect( (**( plugInData -> port -> visRgn)).rgnBBox );
plugInData -> mWC -> Draw();
}
return noErr; /* the framework sample always returns noErr */
} /* end HandleUpdateMessage */
/* ————————————————————————————— HandleIdleMessage ————————————————————————————————
Purpose: Handles idle tasks. The kVisualPluginIdleMessage will be received
only if the kVisualWantsIdleMessages bit was set in
playerMessageInfo.u.registerVisualPluginMessage.options in main().
———————————————————————————————————————————————————————————————————————————————————
Arguments: plugInData - VisHandlerData struct
———————————————————————————————————————————————————————————————————————————————————
Returns: status
———————————————————————————————————————————————————————————————————————————————————
*/
OSStatus HandleIdleMessage (VisHandlerData *plugInData)
{
OSStatus status = noErr;
//RenderVisual(plugInData);
if ( plugInData -> mWC ) {
plugInData -> mWC -> RecordSample( EgOSUtils::CurTimeMS(), plugInData -> mSample );
plugInData -> mWC -> Draw();
}
return status; /* the framework sample always returns noErr */
} /* end HandleIdleMessage */
void HandlePlugInMouseDown (VisHandlerData *plugInData,EventRecord *theEvent)
{
/*
MenuHandle thePopUp;
SInt32 menuResult;
SInt16 theItem;*/
Point pt = theEvent -> where;
static long sLastWhen = 0;
long curTime = ::TickCount();
if ( plugInData -> mWC -> PtInTitle( pt ) || ( theEvent -> modifiers & cmdKey ) )
plugInData -> mWC -> SelectConfig();
// else if ( plugInData -> mWC -> IsAtFullScreen() )
// plugInData -> mWC -> SetFullScreen( false );
else if ( curTime - sLastWhen < ::GetDblTime() )
plugInData -> mWC -> SetFullScreen( true );
else
sLastWhen = curTime;
}